﻿using System.Runtime.CompilerServices;
using dtPolyRef = System.UInt32;
using dtTileRef = System.UInt32;
using dtStatus = System.UInt32;
using dtPathQueueRef = System.UInt32;
using dtObstacleRef = System.UInt32;
using dtCompressedTileRef = System.UInt32;
using rcSizeType = System.Int64;
using flzuint8 = System.Byte;
using flzuint16 = System.UInt16;
using flzuint32 = System.UInt32;
using TimeVal = System.Int64;
using System.Runtime.InteropServices;

namespace Recast
{
    public unsafe partial class RecastApiGlobal
    {
        public static long RC_SIZE_MAX = long.MaxValue;
        public static float FLT_MAX = 3.402823466e+38F;

        public static float roundf(float f) 
        {
            return (float)Math.Round(f);
        }

        [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void* memset(void* _Dst, int _Val, int _Size);

        public static void memcpy(void* _Dst, void* _Src, int _Size)
        {
            byte* destPtr = (byte*)_Dst;
            byte* srcPtr = (byte*)_Src;
            for (int i = 0; i < _Size; i++)
            {
                destPtr[i] = srcPtr[i];
            }
        }

        [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void qsort(void* _Base, int _NumOfElements, int _SizeOfElements, CompareItemX _CompareFunction);

        public delegate int CompareItemX(void* va, void* vb);

        public static T* reinterpret_cast<T>(byte* buffer)
        {
            return (T*)buffer;
        }

        public static T static_cast<T>(void* ptr)
        {
            return Marshal.PtrToStructure<T>((nint)ptr);
        }

        public static T* newObj<T>() where T : new()
        {
            T* ptr = (T*)Marshal.AllocHGlobal(sizeof(T));
            *ptr = new T();
            return ptr;
        }

        public static void delete<T>(T* ptr)
        {
            if (ptr == null)
                return;
            Marshal.FreeHGlobal((IntPtr)ptr);
        }

        public static T* newArray<T>(int size) where T : new() 
        {
            T* ptr = (T*)Marshal.AllocHGlobal(sizeof(T) * size);
            for (int i = 0; i < size; i++)
            {
                ptr[i] = new T();
            }
            return ptr;
        }

        public static void deleteArray<T>(T* ptr) 
        {
            if (ptr == null)
                return;
            Marshal.FreeHGlobal((IntPtr)ptr);
        }
    }
}
